#pragma once

#include<iostream>
#include<sys/socket.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/wait.h>
#include<netinet/in.h>
#include<cstring>
#include<arpa/inet.h>
#include<fcntl.h>
#include<signal.h>
#include<pthread.h>
#include"Thread_pool.hpp"
#include"Task.hpp"
#define BACK_LOG 5

using namespace std;
class prama{
    public:
        int sock;
        std::string ip;
        int port;
    public:
        prama(int _sock, std::string _ip, int _port)
            :sock(_sock),ip(_ip), port(_port)
        {}
        ~prama()
        {}
};

//服务器端 需要关注ip地址，port给定即可
class TcpSever
{
  private:
    int port;//三次握手  监听 接受
    int lsock;
    ThreadPool<Task>*tp;
  public:
    TcpSever(int _port) : port(_port)  ,lsock(-1)
    {}
    bool init_tcp_sever()
    {
      lsock=socket(AF_INET,SOCK_STREAM,0);
      //判断是否创建成功
      if(lsock<0)
      {
        cerr<<"creat sock fail"<<endl;
        return false;
      }
      //ip和端口绑定，表示网络中唯一的进程
      struct sockaddr_in local;
      memset(&local,0,sizeof(local));
      local.sin_family=AF_INET;
      local.sin_port=htons(port);
      local.sin_addr.s_addr=INADDR_ANY;//接受任意ip传信息，设置传入数据的ip


      if(bind(lsock,(struct sockaddr*)&local,sizeof(local))<0)
      {
        //绑定失败
        cout<<"bind fail "<<endl;
        return false;
      }
      //绑定成功，监听连接的ip
      if(listen(lsock,BACK_LOG)<0)
      {
        cout<<" listen fail "<<endl;
        return false;
      }
      tp =new ThreadPool<Task>();
      //绑定成功  监听成功  有ip连接到服务端
      return true;
    }

   //static void sevice(int sock,string ip,int port)
   // {
   //     char buffer[1024];
   //     while(1)
   //     {
   //       //读取数据
   //       ssize_t size=read(sock,buffer,sizeof(buffer)-1);
   //       if(size>0)
   //       {
   //         buffer[size]=0;
   //         cout<<ip<<":"<<port<<":"<<" #  "<<buffer<<endl;
   //         //让客户端也收到信息
   //         write(sock,buffer,size);
   //       }
   //       else if(size==0)
   //       {
   //         //没数据了，对端关闭
   //         cout<<ip<<":"<<port<<":"<<"close"<<endl;
   //         break;
   //       }
   //       else
   //       {
   //         cout<<sock<<"read fail"<<endl;
   //         break;
   //       }
   //     }
   //     cout<<"sevice done "<<endl;
   // }
   //static void*  rountine(void *arg)
   // {
   //   prama *p=(prama*)arg;
   //   pthread_detach(pthread_self());
   //   sevice(p->sock,p->ip,p->port);
   //    close(p->sock);
   //   delete p;
   //   return nullptr;

   // }
    void Loop()
    {
     // signal(SIGCHLD,SIG_IGN);
      struct sockaddr_in peer;
      tp->Thread_pool_init();
      for(;;)
      {
        socklen_t len=sizeof(peer);
        //接受套接字，服务
        int sock=accept(lsock,(struct sockaddr*)&peer,&len);
        if(sock<0)
        {
          cout<<"accept fail continue next"<<endl;
          continue;
        }

         string ip=inet_ntoa(peer.sin_addr);//需要从网络整形变成网址的样子
         int port=ntohs(peer.sin_port);
        Task t(sock,ip,port);
        //创建线程池实现先有线程再对来的任务直接服务
        tp->push(t);  
        


      //创建多线程解决
   //   pthread_t tid;
   //   string ip=inet_ntoa(peer.sin_addr);//需要从网络整形变成网址的样子
   //   int port=ntohs(peer.sin_port);
   //   //定义结构体，把结构体传过去
   //   prama *p=new prama(sock,ip,port);
   //   pthread_create(&tid,nullptr,rountine,p);
      }
    }



        //接受成功，对客户端进行服务，使用多进程服务
   //    //让孙子进程服务，被系统领养
   //     pid_t id=fork();
   //     if(id==0)
   //     {
   //       //爸爸进程
   //       close(lsock);
   //       if(fork()>0)
   //       {
   //         //爸爸进程退出
   //         exit(0);
   //       }
   //       //孙子进程服务
   //       string ip=inet_ntoa(peer.sin_addr);//需要从网络整形变成网址的样子
   //       int port=ntohs(peer.sin_port);
   //       cout << "get a new link->"<< sock << " [" << ip << "]:" << port << endl;
   //       sevice(sock,ip,port);
   //       exit(0);
   //     }
   //     close(sock);
   //     waitpid(id,nullptr,0);
    //  }
   // }
    ~TcpSever()
    {
      if(lsock>=0)
      {
        close(lsock);
      }
    }
};
